package com.example.forward.rxjava;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Observer;
import rx.Scheduler;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.functions.Func2;

public class MainActivity extends AppCompatActivity {

    private Subscriber<String> mSubscriber;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initSubscribler();
//        creates();
//        from();
//        just();
//        repeat();
//        range();
//        interval();
//        timer();
//        filter();
//        take();
//        distinct();
//        skip();
//        elementAt();
//        sample();
//        tansformMap();
        scan();
    }

    private void initSubscribler() {
        mSubscriber = new Subscriber<String>() {

            @Override
            public void onCompleted() {
                Log.i("ljh", "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.i("ljh", "onError " + e.toString());
            }

            @Override
            public void onNext(String s) {
                Log.i("ljh", s);
            }

            @Override
            public void onStart() {
                Log.i("ljh", "onStart");
            }
        };
    }

    private void creates() {
        Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onStart();
                for (int i = 0; i < 20; i++) {
                    subscriber.onNext("num " + i);
                    if (i == 5) {
                        subscriber.onError(new Throwable("=5"));
                    }
                }
                subscriber.onCompleted();
            }
        });
        observable.subscribe(mSubscriber);
    }

    private void from() {
        List<String> items = new ArrayList<>();
        items.add("1");
        items.add("10");
        items.add("100");
        items.add("1000");
        Observable<String> observable = Observable.from(items);
        observable.subscribe(mSubscriber);
    }

    private void just() {
        Observable<String> just = Observable.just("a", "b", "c", "e");
        just.subscribe(mSubscriber);
    }

    private void repeat() {
        Observable<String> just = Observable.just("a", "b", "c", "e").repeat(3);
        just.subscribe(mSubscriber);
    }

    private void range() {
        Observable.range(10, 3)
                .subscribe(new Observer<Integer>() {

                    @Override
                    public void onCompleted() {
                        Log.i("ljh", "onCompleted");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i("ljh", "onError " + e.toString());
                    }

                    @Override
                    public void onNext(Integer number) {
                        Log.i("ljh", "onNext " + number);
                    }
                });
    }

    private void interval() {
        Observable.interval(3, TimeUnit.SECONDS).subscribe(new Observer<Long>() {
            @Override
            public void onCompleted() {
                Log.i("ljh", "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.i("ljh", "onError " + e.toString());
            }

            @Override
            public void onNext(Long number) {
                Log.i("ljh", "onNext " + number);
            }
        });
    }

    private void timer() {
        Observable.timer(3, TimeUnit.SECONDS).subscribe(new Observer<Long>() {
            @Override
            public void onCompleted() {
                Log.i("ljh", "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.i("ljh", "onError " + e.toString());
            }

            @Override
            public void onNext(Long number) {
                Log.i("ljh", "onNext " + number);
            }
        });
    }

    private void filter() {
        Observable.just("a", "b", "c", "d")
                .filter(new Func1<String, Boolean>() {
                    @Override
                    public Boolean call(String s) {
                        return s.startsWith("c");
                    }
                })
                .subscribe(mSubscriber);
    }

    private void take() {
        //take()函数用整数N来作为一个参数，从原始的序列中发射前N个元素，然后完成：
        Observable.just("a", "b", "c", "d")
//                .take(2)
                .takeLast(3)
                .subscribe(mSubscriber);
    }

    private void distinct() {
        //去重
        Observable.just("a", "b", "a", "c", "d")
//                .repeat(3)
                .distinct()
                .subscribe(mSubscriber);
    }

    private void skip() {
        Observable.just("a", "b", "c", "d")
//                .skip(2)
                .skipLast(2)
                .subscribe(mSubscriber);
    }

    private void elementAt() {
        Observable.just("a", "b", "c", "d")
//                .elementAt(5)
                .elementAtOrDefault(5, "null")
                .subscribe(mSubscriber);
    }

    private void sample() {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            list.add("i = " + i);
        }
        Observable.from(list)
                .sample(2, TimeUnit.MILLISECONDS)
                .subscribe(mSubscriber);
    }

    private void tansformMap() {
        //转换类型
        Observable.just(1, 2, 3, 4, 5)
                .map(new Func1<Integer, String>() {
                    @Override
                    public String call(Integer integer) {
                        return "the position id " + integer;
                    }
                })
                .subscribe(mSubscriber);
    }

    private void scan() {
        //类似递归
        Observable.just(1, 2, 3, 4, 5, 6)
                .scan(new Func2<Integer, Integer, Integer>() {
                    @Override
                    public Integer call(Integer integer, Integer integer2) {
                        return integer * integer2;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.i("ljh", integer + "");
                    }
                });
    }
}
